using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using ACS.Debugger.Core.Impl;
using ACS.Debugger.Core.Interfaces;

namespace ACS.Debugger.Core.Wrappers
{
    public class ManagedCallback : ICorDebugManagedCallback, ICorDebugManagedCallback2
    {
        private ICorDebugProcess _process;
        private ICorDebugModule _module;

        public ICorDebugProcess Process
        {
            get { return _process; }
            set { _process = value; }
        }

        public ICorDebugModule Module
        {
            get { return _module; }
        }

        public void Breakpoint(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread,
                               ICorDebugBreakpoint pBreakpoint)
        {
            try 
            {
            ICorDebugFunctionBreakpoint functionBreakpoint;//we need to initialize this variable
            uint num;
            //store current thread
            Debugger.Instance.SetCurrentThread(pThread);
            
            functionBreakpoint = (ICorDebugFunctionBreakpoint)pBreakpoint;
            functionBreakpoint.GetOffset(out num);
            
            Console.WriteLine(num);
            
            int dwashit = Debugger.Instance.GetSourceLine((int)num);
            Console.WriteLine(dwashit);
            _process.Continue(0);
            }
            catch(Exception e)
            {
                Console.WriteLine(e.StackTrace);
            }
        }

        public void StepComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugStepper pStepper,
                                 CorDebugStepReason reason)
        {
            _process.Continue(0);
        }

        public void Break(ICorDebugAppDomain pAppDomain, ICorDebugThread thread)
        {
            Debugger.Instance.SetCurrentThread(thread);
            
            _process.Continue(0);
        }

        public void Exception(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, int unhandled)
        {
            _process.Continue(0);
        }

        public void EvalComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugEval pEval)
        {
            _process.Continue(0);
        }

        public void EvalException(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugEval pEval)
        {
            _process.Continue(0);
        }

        public void CreateProcess(ICorDebugProcess pProcess)
        {
            _process.Continue(0);
        }

        public void ExitProcess(ICorDebugProcess pProcess)
        {
            _process.Continue(0);
        }

        public void CreateThread(ICorDebugAppDomain pAppDomain, ICorDebugThread thread)
        {
            Console.WriteLine("creating thread");
            _process.Continue(0);
        }

        public void ExitThread(ICorDebugAppDomain pAppDomain, ICorDebugThread thread)
        {
            _process.Continue(0);
        }

        public void LoadModule(ICorDebugAppDomain pAppDomain, ICorDebugModule pModule)
        {
            StringBuilder moduleName = new StringBuilder(256);

            uint len;
            pModule.GetName(256, out len, moduleName);

            string name = moduleName.ToString();

            if (name.Contains("acs.samplecode.exe"))
            {
                //store module.
                _module = pModule;
                Debugger.Instance.ModuleName = name;
                Debugger.Instance.SetBreakpoint(12);
                Debugger.Instance.SetBreakpoint(11);
               // Debugger.Instance.SetBreakpoint(13);
            }

            _process.Continue(0);

        }

        public void UnloadModule(ICorDebugAppDomain pAppDomain, ICorDebugModule pModule)
        {
            _process.Continue(0);
        }

        public void LoadClass(ICorDebugAppDomain pAppDomain, ICorDebugClass c)
        {
            //Console.WriteLine(c.ToString());
            _process.Continue(0);
        }

        public void UnloadClass(ICorDebugAppDomain pAppDomain, ICorDebugClass c)
        {
            _process.Continue(0);
        }

        public void DebuggerError(ICorDebugProcess pProcess, int errorHR, uint errorCode)
        {
            _process.Continue(0);
        }

        public void LogMessage(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, int lLevel,
                               ref ushort pLogSwitchName, ref ushort pMessage)
        {
            _process.Continue(0);
        }

        public void LogSwitch(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, int lLevel, uint ulReason,
                              ref ushort pLogSwitchName, ref ushort pParentName)
        {
            _process.Continue(0);
        }

        public void CreateAppDomain(ICorDebugProcess pProcess, ICorDebugAppDomain pAppDomain)
        {
            pAppDomain.Attach();
            _process.Continue(0);
        }

        public void ExitAppDomain(ICorDebugProcess pProcess, ICorDebugAppDomain pAppDomain)
        {
            _process.Continue(0);
        }

        public void LoadAssembly(ICorDebugAppDomain pAppDomain, ICorDebugAssembly pAssembly)
        {
            _process.Continue(0);
        }

        public void UnloadAssembly(ICorDebugAppDomain pAppDomain, ICorDebugAssembly pAssembly)
        {
            _process.Continue(0);
        }

        public void ControlCTrap(ICorDebugProcess pProcess)
        {
            _process.Continue(0);
        }

        public void NameChange(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread)
        {
            _process.Continue(0);
        }

        public void UpdateModuleSymbols(ICorDebugAppDomain pAppDomain, ICorDebugModule pModule,
                                        IStream pSymbolStream)
        {
            _process.Continue(0);
        }

        public void EditAndContinueRemap(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread,
                                         ICorDebugFunction pFunction, int fAccurate)
        {
            _process.Continue(0);
        }

        public void BreakpointSetError(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread,
                                       ICorDebugBreakpoint pBreakpoint, uint dwError)
        {
            _process.Continue(0);
        }

        public void FunctionRemapOpportunity(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread,
                                             ICorDebugFunction pOldFunction, ICorDebugFunction pNewFunction,
                                             uint oldILOffset)
        {
            _process.Continue(0);
        }

        public void CreateConnection(ICorDebugProcess pProcess, uint dwConnectionId, ref ushort pConnName)
        {
            _process.Continue(0);
        }

        public void ChangeConnection(ICorDebugProcess pProcess, uint dwConnectionId)
        {
            _process.Continue(0);
        }

        public void DestroyConnection(ICorDebugProcess pProcess, uint dwConnectionId)
        {
            _process.Continue(0);
        }

        public void Exception(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFrame pFrame,
                              uint nOffset, CorDebugExceptionCallbackType dwEventType, uint dwFlags)
        {
            _process.Continue(0);
        }

        public void ExceptionUnwind(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread,
                                    CorDebugExceptionUnwindCallbackType dwEventType, uint dwFlags)
        {
            _process.Continue(0);
        }

        public void FunctionRemapComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread,
                                          ICorDebugFunction pFunction)
        {
            _process.Continue(0);
        }

        public void MDANotification(ICorDebugController pController, ICorDebugThread pThread, ICorDebugMDA pMDA)
        {
            _process.Continue(0);
        }
    }

}
